package com.polaris.live

import android.app.Activity
import android.app.Application
import android.content.Context
import android.os.Bundle
import androidx.core.os.bundleOf
import androidx.core.provider.FontRequest
import androidx.emoji.text.EmojiCompat
import androidx.emoji.text.FontRequestEmojiCompatConfig
import com.adjust.sdk.Adjust
import com.blankj.utilcode.util.GsonUtils
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.google.firebase.ktx.Firebase
import com.google.gson.GsonBuilder
import com.hjq.language.LocaleContract
import com.hjq.language.MultiLanguages
import com.polaris.live.cache.CommonCache
import com.polaris.live.common.AppModule
import com.polaris.live.common.cacha.CacheUtil
import com.polaris.live.common.cacha.OnAppForceUpgrade
import com.polaris.live.common.cacha.OnLogoutTrigger
import com.polaris.live.common.cacha.UserManager
import com.polaris.live.common.constant.ConfigType
import com.polaris.live.common.constant.ServerConfig
import com.polaris.live.common.manager.CoroutineScopeManager
import com.polaris.live.common.util.OnAccountChangeListener
import com.polaris.live.common.util.OnGameAccountChangeListener
import com.polaris.live.common.util.OnLevelAccountChangeListener
import com.polaris.live.common.util.ToastGravity
import com.polaris.live.common.util.UserAccountUtils
import com.polaris.live.common.util.ViewUtils
import com.polaris.live.dialog.GlobalDialogManager
import com.polaris.live.floating.FloatingWindowManager
import com.polaris.live.im.manager.ImNoticeManager
import com.polaris.live.manager.AdJustManager
import com.polaris.live.manager.AssetsConfigManager
import com.polaris.live.manager.GoogleInstallReferrerManager
import com.polaris.live.manager.GooglePayManager
import com.polaris.live.manager.GoogleRecaptchaManager
import com.polaris.live.manager.MNotificationManager
import com.polaris.live.translation.R.string
import com.polaris.live.utils.EmojiUtils
import com.polaris.live.utils.EmptyEmojiAndroidProvider
import com.polaris.live.utils.OtherPermissionUtils
import com.polaris.live.utils.UserUtils
import com.polaris.live.utils.file.FileUtils
import com.polaris.live.utils.zego.beauty.FaceManager
import com.scwang.smart.refresh.footer.ClassicsFooter
import com.scwang.smart.refresh.header.MaterialHeader
import com.scwang.smart.refresh.layout.SmartRefreshLayout
import com.tencent.mmkv.MMKV
import com.uuzuche.lib_zxing.activity.ZXingLibrary
import com.vanniktech.emoji.EmojiManager
import com.vanniktech.emoji.googlecompat.GoogleCompatEmojiProvider
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.libpag.PAGDiskCache
import ren.yale.android.cachewebviewlib.WebViewCacheInterceptor
import ren.yale.android.cachewebviewlib.WebViewCacheInterceptorInst
import ren.yale.android.cachewebviewlib.config.CacheExtensionConfig
import java.io.File
import java.util.Locale

/**
 * App
 *
 * @author Created by 半仙 on 2023/7/31/031 16:29
 */
class App : Application() {

    companion object {

        lateinit var instance: App

        private lateinit var appContext: Context

        fun getAppContext(): Context {
            return appContext
        }

        init {
            UserManager.onLogoutTrigger = OnLogoutTrigger { _, delay ->
                GlobalScope.launch(CoroutineScopeManager.mainDispatcher) {
                    if (delay > 0) {
                        delay(delay)
                    }

                    if (UserUtils.logout()) {
                        delay(500)

                        ToastGravity.showGravity(string.user_token_invalid)
                    }
                }
            }
            UserManager.onAppForceUpgrade = OnAppForceUpgrade { vo ->
                CoroutineScopeManager.mainScope.launch {
                    ViewUtils.getAliveTopActivity()?.also {
                        GlobalDialogManager.showUpgradeDialog(it, vo)
                    }
                }
            }
            UserAccountUtils.onAccountChangeListener = OnAccountChangeListener {
                GlobalScope.launch(CoroutineScopeManager.mainDispatcher) {
                    ImNoticeManager.dispatchAccountChange(it)
                }
            }

            UserAccountUtils.onGameAccountChangeListener = OnGameAccountChangeListener {
                GlobalScope.launch(CoroutineScopeManager.mainDispatcher) {
                    ImNoticeManager.dispatchGameAccountChange(it)
                }
            }
            UserAccountUtils.onLevelAccountChangeListener = OnLevelAccountChangeListener {
                GlobalScope.launch(CoroutineScopeManager.mainDispatcher) {
                    ImNoticeManager.dispatchLevelAccountChange(it)
                }
            }
        }

        //进入mainActivity后是否初始化过状态
        var isInitState = false
        fun onInitState(keepExecute: () -> Unit) {
            if (!isInitState) {
                isInitState = true
                keepExecute.invoke()
            }
        }
    }

    init {
        SmartRefreshLayout.setDefaultRefreshInitializer { _, layout ->
            layout.setEnableRefresh(true)
            layout.setEnableLoadMore(true)
            layout.setEnableAutoLoadMore(true)
            layout.setDisableContentWhenRefresh(false)
            layout.setDisableContentWhenLoading(false)
            layout.layout.tag = "close egg"
        }

        SmartRefreshLayout.setDefaultRefreshHeaderCreator { context, layout ->
            layout.setEnableHeaderTranslationContent(false)
            MaterialHeader(context)
        }
        SmartRefreshLayout.setDefaultRefreshFooterCreator { context, _ ->
            ClassicsFooter(
                context
            )
        }
    }

    override fun attachBaseContext(base: Context?) {
        if (base != null) {
            val systemLanguage = MultiLanguages.getSystemLanguage(base)
            // 如果当前语种既不是中文（包含简体和繁体）和英语（包含美式英式等），就默认设置成英文的，避免跟随系统语种
            if (!MultiLanguages.equalsLanguage(
                    systemLanguage,
                    LocaleContract.getSimplifiedChineseLocale()
                )
                && !MultiLanguages.equalsLanguage(
                    systemLanguage,
                    LocaleContract.getTraditionalChineseLocale()
                )
                && !MultiLanguages.equalsLanguage(systemLanguage, LocaleContract.getEnglishLocale())
                && !MultiLanguages.equalsLanguage(systemLanguage, LocaleContract.getArabicLocale())
                && !MultiLanguages.equalsLanguage(
                    systemLanguage,
                    LocaleContract.getPortugalLocale()
                )
                && !MultiLanguages.equalsLanguage(
                    systemLanguage,
                    LocaleContract.getJapaneseLocale()
                )
                && !MultiLanguages.equalsLanguage(systemLanguage, LocaleContract.getKoreanLocale())
                && !MultiLanguages.equalsLanguage(systemLanguage, LocaleContract.getSpainLocale())
                && !MultiLanguages.equalsLanguage(systemLanguage, LocaleContract.getMalayLocale())
                && !MultiLanguages.equalsLanguage(systemLanguage, LocaleContract.getTurkishLocale())
                && !MultiLanguages.equalsLanguage(systemLanguage, LocaleContract.getHindiLocale())
            ) {
                MultiLanguages.setDefaultLanguage(LocaleContract.getEnglishLocale())
            } else {
                when (systemLanguage.language) {
                    "zh" -> {
                        if (systemLanguage.toString().contains("zh_CN")) {
                            MultiLanguages.setDefaultLanguage(LocaleContract.getSimplifiedChineseLocale())
                        } else if (systemLanguage.toString().contains("zh_HK")
                            || systemLanguage.toString().contains("zh_TW")
                        ) {
                            MultiLanguages.setDefaultLanguage(LocaleContract.getTraditionalChineseLocale())
                        } else {
                            MultiLanguages.setDefaultLanguage(LocaleContract.getSimplifiedChineseLocale())
                        }
                    }

                    "en" -> {
                        MultiLanguages.setDefaultLanguage(LocaleContract.getEnglishLocale())
                    }

                    "ar" -> {
                        MultiLanguages.setDefaultLanguage(LocaleContract.getArabicLocale())
                    }

                    "pt" -> {
                        MultiLanguages.setDefaultLanguage(LocaleContract.getPortugalLocale())
                    }

                    "ja" -> {
                        MultiLanguages.setDefaultLanguage(LocaleContract.getJapaneseLocale())
                    }

                    "ko" -> {
                        MultiLanguages.setDefaultLanguage(LocaleContract.getKoreanLocale())
                    }

                    "es" -> {
                        MultiLanguages.setDefaultLanguage(LocaleContract.getSpainLocale())
                    }

                    "ms" -> {
                        MultiLanguages.setDefaultLanguage(LocaleContract.getMalayLocale())
                    }

                    "tr" -> {
                        MultiLanguages.setDefaultLanguage(LocaleContract.getTurkishLocale())
                    }

                    "hi" -> {
                        MultiLanguages.setDefaultLanguage(LocaleContract.getHindiLocale())
                    }

                    "vi" -> {
                        MultiLanguages.setDefaultLanguage(LocaleContract.getVietnameseLocale())
                    }
                }
            }
        }
        // 绑定语种
        super.attachBaseContext(MultiLanguages.attach(base))
    }

    override fun onCreate() {
        super.onCreate()
        appContext = applicationContext
        instance = this

        // 初始化语种切换框架
        MultiLanguages.init(this)

        //adjust
        registerActivityLifecycleCallbacks(AdjustLifecycleCallbacks())

        FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(true)
        FirebaseCrashlytics.getInstance().setCustomKey("env", ServerConfig.getConfigMode().value)
        FirebaseCrashlytics.getInstance().setCustomKey("androidId", AppModule.getDeviceId())

        Firebase.analytics.setUserProperty("androidId", AppModule.getDeviceId())
        Firebase.analytics.setDefaultEventParameters(bundleOf(FirebaseAnalytics.Param.VALUE to 0.0))

        //全局异常捕获
        Thread.setDefaultUncaughtExceptionHandler(CustomUncaughtExceptionHandler())

        //初始化mmkv
        MMKV.initialize(this)
        //gson init
        GsonUtils.setGsonDelegate(GsonBuilder().disableHtmlEscaping().create())

        //其他先处理环境
        initServerConfig()

        //初始化AppModule  主要用于拿一些配置
        AppModule.init(this)
        //adjust
        AdJustManager.init(this)
        //google人机验证
        GoogleRecaptchaManager.init(this)
        //google支付
        GooglePayManager.init()
        //登录相关
        UserUtils.loginInit()

        asyncInit()

        setGlobalTextDirection()
        webCacheInit()
        //二维码
        ZXingLibrary.initDisplayOpinion(this)

        //注册用户通知通道
        MNotificationManager.init()
    }

    private fun setGlobalTextDirection() {
        val configuration = resources.configuration
        configuration.setLayoutDirection(Locale.getDefault())
        resources.updateConfiguration(configuration, resources.displayMetrics)
    }

    private fun webCacheInit() {
        CacheExtensionConfig.addGlobalExtension("json")

        val builder = WebViewCacheInterceptor.Builder(this)
        builder.setCachePath(File(FileUtils.getCacheDir("webCache"))) //设置缓存路径，默认getCacheDir，名称CacheWebViewCache
            .setDynamicCachePath(File(FileUtils.getCacheDir("webDynamicCache")))
            .setCacheSize(
                FileUtils.convertFileSize(500f, FileUtils.SIZE_MB).toLong()
            ) //设置缓存大小，默认100M
            .setConnectTimeoutSecond(20) //设置http请求链接超时，默认20秒
            .setReadTimeoutSecond(20) //设置http请求链接读取超时，默认20秒

        WebViewCacheInterceptorInst.getInstance().init(builder)
    }

    private class AdjustLifecycleCallbacks : ActivityLifecycleCallbacks {

        override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
        }

        override fun onActivityStarted(activity: Activity) {
        }

        override fun onActivityResumed(activity: Activity) {
            Adjust.onResume()
            FloatingWindowManager.resumeActivity(activity)
            OtherPermissionUtils.resumeActivity(activity)
        }

        override fun onActivityPaused(activity: Activity) {
            Adjust.onPause()
        }

        override fun onActivityStopped(activity: Activity) {
        }

        override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
        }

        override fun onActivityDestroyed(activity: Activity) {
        }
    }

    //异步初始化
    private fun asyncInit() {
        AssetsConfigManager.initAllAreaCode()
        AssetsConfigManager.initResourceSDK()
        AssetsConfigManager.assetsLoadFilePag()
        //美颜
        FaceManager.init()

        //emoji
        GlobalScope.launch(CoroutineScopeManager.defaultDispatcher) {
            //先占位，防止后面加载不及时导致崩溃
            try {
                EmojiManager.install(EmptyEmojiAndroidProvider())
            } catch (_: Exception) {
            }

            EmojiManager.install(
                GoogleCompatEmojiProvider(
                    EmojiCompat.init(
                        FontRequestEmojiCompatConfig(
                            this@App,
                            FontRequest(
                                "com.google.android.gms.fonts",
                                "com.google.android.gms",
                                "Noto Color Emoji Compat",
                                EmojiUtils.emojiId,
                            )
                        ).setReplaceAll(true)
                    )
                )
            )
        }

        GlobalScope.launch(CoroutineScopeManager.ioDispatcher) {
            PAGDiskCache.SetMaxDiskSize(1024 * 1024 * 300)

            GoogleInstallReferrerManager.init(this@App)
            CommonCache.clearInstallTime()
        }
    }

    private fun initServerConfig() {
        val serverEnv = BuildConfig.SERVER_ENV
        val debug = BuildConfig.DEBUG

        //线上不允许自定义
        val debugUrl = if (serverEnv == ConfigType.PROD.value) {
            null
        } else {
            CacheUtil.getDebugUrlFromKV()
        }
        val debugEnv = if (serverEnv == ConfigType.PROD.value) {
            null
        } else {
            CacheUtil.getDebugEnvFromKV()
        }
        val url = if (debugEnv == null) {
            debugUrl ?: CacheUtil.getCurrentUrlFromKV()
        } else {
            null
        }
        val domainUrls = CacheUtil.getDomainUrlsFromKV()
        val finalServerEnv = debugEnv ?: serverEnv

        if (!url.isNullOrEmpty() || !domainUrls.isNullOrEmpty()) {
            ServerConfig.initCustomConfig(finalServerEnv, debug, url, domainUrls)
        } else {
            ServerConfig.initConfig(finalServerEnv, debug)
        }
    }
}